package game;



import interfaces.ActionInterface;
import interfaces.AgentInterface;
import interfaces.impl.HumanInteraction;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import objects.ImageObject;
import objects.SpetialFeature;
import objects.WorldObject;
import space.Space;
import universe.Universe;
import util.CledaConnector;
import agents.UniverseAgentWin;
import constants.Constants;
import constants.Message;
import database.MAction;
import database.MAgent;
import database.MSpecialFeature;
import database.MWorld;
import database.MWorldObject;
import extra.Position;
import factoryGame.ObjectFactory;
import game.constants.ReferenceObject;

public class GameStarcraft extends GameServer{
	
	
	public GameStarcraft(){
		space = new Space();
	}
	
	private void setImages() {
		int i = 0;
		for(Universe universe : space.getUniverseList()){	    
			
		    
			ArrayList<WorldObject> listObjects = new ArrayList<WorldObject>();
			for(WorldObject obj : universe.getListObjects()){
	
				System.out.println("Estoy asignando imagenes de lo que carge");
				double x = obj.getPosition().getX();
				double y = obj.getPosition().getY();
				int id = obj.getID();
				
				ArrayList<SpetialFeature> listFea = (ArrayList<SpetialFeature>) obj.getListFeatures().clone();
			
			
				System.out.println("abcd abdc abcd");
				int owner = obj.getOwner();
				obj = ObjectFactory.createWorldObject(obj.getObjectReference(),obj.getOwner(),x,y,Constants.NO_ASSIGN_SPECIAL_FEATURE);
				double xMid =obj.getImageObject().getImageToShow().getWidth()/2;
				double yMid =obj.getImageObject().getImageToShow().getHeight()/2;
				obj.setID(id);
				
				obj.setOwner(owner);
				obj.getImageObject().setPosition(new Position(x-xMid,y-yMid));
				obj.setPosition(new Position(x,y));
				//obj.setID(id);
				
				for(SpetialFeature fea : listFea){
					obj.addSpetialFeature(fea);
					System.out.println("SPETIAL FEATURE NAME: "+fea.getName());
				}
				
				listObjects.add(obj);
				System.out.println(obj.getImageObject().getCollisionShape().getHeight()+"Width y height Game Rol");
				
				for(WorldObject obj1 : obj.getListObjects()){
					System.out.println("ASDASFSAFSDFAFDASFDASFASDFASFSFASFDSAFDSFDSFDSFASDFDFERRRRRRRRRRRRRR");
				}
				
			}
			
			
			universe.setListObjects(listObjects);
			universe.setBackgroundObject(ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_BACKGROUND_1, Constants.NO_OWNER,0,0,Constants.NO_ASSIGN_SPECIAL_FEATURE));
			if(i==1){
				universe.setBackgroundObject(ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_BACKGROUND_2, Constants.NO_OWNER,0,0,Constants.NO_ASSIGN_SPECIAL_FEATURE));
			}
			i++;
			
		}
		
	}
	
	public void load(InputStream is){
		//Obtiene
			Session session = CledaConnector.getInstance().getSession();
		    session.beginTransaction();
			//usa
			List<MWorldObject> list = new ArrayList<MWorldObject>();
			list =session.createCriteria(MWorldObject.class).list();
			session.getTransaction().commit();
		    // SE CIERRA
		    session.close();
			    
			    if(!list.isEmpty()){
			    	space= new Space();
			    	space.loadDatabase();
			    	setImages();
			    	System.out.println("CARGO DE LA BASE DE DATOS 120 aaa "+space.getUniverseList().get(0).getListObjects().size());
			    }
			    
			    if(list.isEmpty()){
			    	//System.out.println("CARGO DE LA BASE DE DATOS 120 bbb "+space.getUniverseList().get(0).getListObjects().size());
			    	space.loadFile(is);
			    	createDatabase();
			    }
		
		
	}
	
private void createDatabase() {
		
		Session session = CledaConnector.getInstance().getSession();
	    session.beginTransaction();
	    
	    int i=0;
	    
		for(Universe universe : space.getUniverseList()){	    
			MWorld mWorld = new MWorld();
		    
			ArrayList<WorldObject> listObjects = new ArrayList<WorldObject>();
			for(WorldObject obj : universe.getListObjects()){

				
				double x = obj.getPosition().getX();
				double y = obj.getPosition().getY();
				
				
				obj = ObjectFactory.createWorldObject(obj.getObjectReference(),Constants.NO_OWNER,x,y,Constants.ASSIGN_SPECIAL_FEATURE);
				double xMid =obj.getImageObject().getImageToShow().getWidth()/2;
				double yMid =obj.getImageObject().getImageToShow().getHeight()/2;
				
				obj.getImageObject().setPosition(new Position(x-xMid,y-yMid));
				obj.setPosition(new Position(x,y));
				
				
				MWorldObject mObj = createObjectDatabase(session,mWorld,obj,null);
				mWorld.getObjectList().add(mObj);
				
				obj.setID(mObj.getId());
				listObjects.add(obj);
				
			}
			
			
			universe.setListObjects(listObjects);
			universe.setBackgroundObject(ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_BACKGROUND_3, Constants.NO_OWNER,0,0,Constants.ASSIGN_SPECIAL_FEATURE));
			
			
			session.save(mWorld);
		}
		
		session.getTransaction().commit();
	    // SE CIERRA
	    session.close();
		
	}

	private MWorldObject createObjectDatabase(Session session, MWorld mWorld, WorldObject obj, MWorldObject father) {
		MWorldObject mWorldObject = new MWorldObject();
		mWorldObject.setWorldReference(mWorld);
		
		//obj.setID(mWorldObject.getId());
		
		if(father!=null){
			mWorldObject.setObjectReference(father);
			father.getObjectList().add(mWorldObject);
		}
		
		//obj.setID(mWorldObject.getId());
		//mWorldObject.setObjectId(obj.getID());
		
		mWorldObject.setObjectRefName(obj.getObjectReference());
		mWorldObject.setOwner(obj.getOwner());
		mWorldObject.setX((int)obj.getPosition().getX());
		mWorldObject.setY((int) obj.getPosition().getY());
		if(obj.isActive()){
			mWorldObject.setActive(Constants.TRUE);
		}else{
			mWorldObject.setActive(Constants.FALSE);
		}
		
		MAction mAction = new MAction();
		
		for (ActionInterface action : obj.getListActions()){
			
			mAction = new MAction();
			mAction.setObjectReference(mWorldObject);
			mAction.setActionId(action.getId());
			mAction.setName(action.getName());
			
			mWorldObject.getActionList().add(mAction);
			session.save(mAction);
			
		}
		
		MAgent mAgent = new MAgent();
		
		for (AgentInterface agent : obj.getListAgents()){
			
			mAgent = new MAgent();
			mAgent.setObjectReference(mWorldObject);
			mAgent.setAgentId(agent.getID());
			mAction.setName(agent.getName());
			
			mWorldObject.getAgentList().add(mAgent);
			session.save(mAgent);
			
		}
		for (HumanInteraction agent : obj.getListHumanInteractions()){
			
			mAgent = new MAgent();
			mAgent.setObjectReference(mWorldObject);
			mAgent.setAgentId(agent.getID());
			mAction.setName(agent.getName());
			
			mWorldObject.getAgentList().add(mAgent);
			session.save(mAgent);
			
		}
		
		MSpecialFeature mSpecialFeature= new MSpecialFeature();
		
		for (SpetialFeature feature : obj.getListFeatures()){
			
			mSpecialFeature= new MSpecialFeature();
			mSpecialFeature.setObjectReference(mWorldObject);
			
			mSpecialFeature.setSpecialFeatureId(feature.getId());
			mSpecialFeature.setName(feature.getName());
			mSpecialFeature.setValue(feature.getValue());
			mSpecialFeature.setAditionalInfo(feature.getAditionalInfo());
			
			
			mWorldObject.getSpecialFeatureList().add(mSpecialFeature);
			session.save(mSpecialFeature);
			
		}
		
		
		for(WorldObject obj1 : obj.getListObjects()){
			obj1.setActive(false);
			createObjectDatabase(session, mWorld, obj1, mWorldObject);
		}
		
		session.save(mWorldObject);
		return mWorldObject;
	}
	
	private void loadObjectsFromDatabase(List<MWorldObject> list, Universe universe) {
		
		WorldObject object = new WorldObject();
		
		for(MWorldObject obj : list){
			
			object= new WorldObject();
			object.setID(obj.getId());
			object.setObjectReference(obj.getObjectRefName());
			object.setOwner(obj.getOwner());
			object.getPosition().setX(obj.getX());
			object.getPosition().setY(obj.getY());
			if(obj.isActive()==Constants.TRUE){
				object.setActive(true);
				System.out.println("ACTIVO OBJETO");
			}else{
				object.setActive(false);
				System.out.println("NO ACTIVO OBJETO");
			}
			
			int owner = object.getOwner();
			object = ObjectFactory.createWorldObject(object.getObjectReference(),object.getOwner(),object.getPosition().getX(),object.getPosition().getY(),Constants.NO_ASSIGN_SPECIAL_FEATURE);
			object.setID(obj.getId());
			object.setOwner(owner);
			
			for(MSpecialFeature mFeature : obj.getSpecialFeatureList()){
				SpetialFeature feature = new SpetialFeature();
				
				feature.setId(mFeature.getSpecialFeatureId());
				feature.setName(mFeature.getName());
				feature.setValue(mFeature.getValue());
				feature.setAditionalInfo(mFeature.getAditionalInfo());
				object.addSpetialFeature(feature);
			}
		
			//assignInactiveObjectsToFather(obj.getObjectList(), universe, object);
			for(MWorldObject obj1 : obj.getObjectList() ){
				assignInactiveObjectsToFather(obj1, universe, object);
				
			}
			
			//assignChild(listChild,universe,object);
			universe.addObject(object);
			String message =Message.POSITION_CAMERA+System.getProperty("line.separator")+object.getPosition().getX()+System.getProperty("line.separator")+object.getPosition().getY();
		}
	}
	
	private void assignInactiveObjectsToFather(MWorldObject obj, Universe universe, WorldObject father) {
		
		WorldObject object = new WorldObject();
		
		System.out.println("MI ID del OBJETO HIJO "+obj.getObjectRefName());
			object.setID(obj.getId());
			object.setObjectReference(obj.getObjectRefName());
			object.setOwner(father.getOwner());
			object.getPosition().setX(obj.getX());
			object.getPosition().setY(obj.getY());
			
			
			if(obj.isActive()==Constants.TRUE){
				object.setActive(true);
				System.out.println("ACTIVO OBJETO");
			}else{
				object.setActive(false);
				System.out.println("NO ACTIVO OBJETO");
			}
			//double x = object.getPosition().getX();
			//double y = object.getPosition().getY();
			object = ObjectFactory.createWorldObject(object.getObjectReference(),object.getOwner(),object.getPosition().getX(),object.getPosition().getY(),Constants.NO_ASSIGN_SPECIAL_FEATURE);
			object.setID(obj.getId());
			//double xMid =object.getImageObject().getImageToShow().getWidth()/2;
			//double yMid =object.getImageObject().getImageToShow().getHeight()/2;
					
			//object.getImageObject().setPosition(new Position(x-xMid,y-yMid));
			//object.setPosition(new Position(x,y));
			
			for(MSpecialFeature mFeature : obj.getSpecialFeatureList()){
				SpetialFeature feature = new SpetialFeature();
				
				feature.setId(mFeature.getSpecialFeatureId());
				feature.setName(mFeature.getName());
				feature.setValue(mFeature.getValue());
				feature.setAditionalInfo(mFeature.getAditionalInfo());
				object.addSpetialFeature(feature);
				
			}
			
			if(obj.isActive()==Constants.TRUE){
				object.setActive(true);
				universe.addObject(object);
			}else{
				object.setActive(false);
				father.addObject(object);
			}
			
			
		}


	@Override
	public void disconnectClient(int idCliente,int universeId) {
		
		Universe universe = space.getUniverse(universeId);
		if(universe==null){
			return ;
		}
		
		//universe.disconnect(idCliente);
		
	}
	@Override
	public ArrayList<ReferenceImageObject> getAllImages() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public ImageObject getImageObject(int objectReference) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public int connectClient(int idCliente) {
		int universeId = Constants.NO_UNIVERSE_ID;
		//para este juego lo connecto en el universo 1
		
		Universe universe = space.getUniverse(1);
		if(universe==null){
			System.out.println("UNIVERSO NULL GAME ROLt");
			return universeId;
		}
		System.out.println("conecto cliente");
		
		Session session = CledaConnector.getInstance().getSession();
	    session.beginTransaction();
		//usa
		List<MWorldObject> list = new ArrayList<MWorldObject>();
	    list =session.createCriteria(MWorldObject.class).add(Restrictions.eq("owner", idCliente)).list();
	    
//	    if(list.isEmpty()){		
//	    	WorldObject player = ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_PLAYER,idCliente,200,700,Constants.ASSIGN_SPECIAL_FEATURE);
//	    	player.setActive(true);
//	    	
//			WorldObject dog = ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_DOG,idCliente,100,100,Constants.ASSIGN_SPECIAL_FEATURE);
//	    	dog.setActive(false);
//	    	
//	    	WorldObject axe = ObjectFactory.createWorldObject(ReferenceObject.OBJECT_REFERENCE_AXE,idCliente,100,100,Constants.ASSIGN_SPECIAL_FEATURE);
//	    	axe.setActive(false);
//			
//			List<MWorld> listWorld = new ArrayList<MWorld>();
//		    listWorld =session.createCriteria(MWorld.class).add(Restrictions.eq("id", 1)).list();
//			
//			MWorld mWorld = listWorld.get(0);
//			
//			MWorldObject mPlayer = createObjectDatabase(session, mWorld, player,null);
//			player.setID(mPlayer.getId());
//			
//			MWorldObject mDog= createObjectDatabase(session, mWorld, dog,null);
//			dog.setID(mDog.getId());
//			
//			MWorldObject mAxe= createObjectDatabase(session, mWorld, axe,null);
//			axe.setID(mAxe.getId());
//			
//			session.getTransaction().commit();
//		    // SE CIERRA
//		    session.close();
//		    
//		    String message =Message.POSITION_CAMERA+System.getProperty("line.separator")+player.getPosition().getX()+System.getProperty("line.separator")+player.getPosition().getY();
//			universe.generateMessage(idCliente, message);
//			
//			
//			player.addObject(dog);
//			player.addObject(axe);
//			
//			universe.addObject(player);
//		    
//			return 1;
//	    }
		
	    boolean loadObjects = true;
	    
	    for(WorldObject obj : universe.getListObjects()){
	    	if(obj.getOwner()==idCliente){
	    		loadObjects=false;
	    	}
	    }
	    
	    if(idCliente != 1 || idCliente != 2){
	    	loadObjects=false;
	    }
	    
	    if(loadObjects){
	    	loadObjectsFromDatabase(list,universe);
	    }
	    
	    
		session.getTransaction().commit();
	    // SE CIERRA
	    session.close();
		return 1;
	}
	
}
	/*@Override
	public int connectClient(int idCliente) {
		/*int universeId = Constants.NO_UNIVERSE_ID;
		//para este juego lo connecto en el universo 1
		
		Universe universe1 = space.getUniverse(1);
		if(universe1==null){
			System.out.println("UNIVERSO NULL GAME ROLt");
			return universeId;
		}
		
		
		
		if(universe1!=null){
			
			for(WorldObject obj : universe1.getListObjectsToAdd()){
				if(obj.getOwner()==idCliente && obj.getObjectReference()==ReferenceObject.OBJECT_REFERENCE_COMMAND_CENTER1){
					String message =Message.POSITION_CAMERA+System.lineSeparator()+obj.getPosition().getX()+System.lineSeparator()+obj.getPosition().getY();
					universe1.generateMessage(idCliente, message);
					System.out.println("ENCONTRE UN OBJETO QUE TIENE MI ID");
					return universe1.getUniverseId();
				}
			}
		}
		
		for(WorldObject obj : universe1.getListObjects()){
			if(obj.getOwner()==idCliente && obj.getObjectReference()==ReferenceObject.OBJECT_REFERENCE_COMMAND_CENTER1){
				String message =Message.POSITION_CAMERA+System.lineSeparator()+obj.getPosition().getX()+System.lineSeparator()+obj.getPosition().getY();
				universe1.generateMessage(idCliente, message);
				System.out.println("ENCONTRE UN OBJETO QUE TIENE MI ID");
				return universe1.getUniverseId();
			}
		}
		
	
		return 1;
		
	}
	
	

	
}*/
